From: Olivier Trichet Date: Wed, 23 Mar 2016 01:23:56 +0000 (+0100) Subject: Use libudev to find serial devices dynamically on Linux X-Git-Tag: archive/raspbian/1.10.0+ds-2+rpi1~1^2~12^2~9^2~9^2~4^2^2 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=ac44161c6b5f4c4b0e74894850eae59fcffb56fa;p=gpsbabel.git Use libudev to find serial devices dynamically on Linux --- diff --git a/gui/app.pro b/gui/app.pro index be158398c..930cfe0f7 100755 --- a/gui/app.pro +++ b/gui/app.pro @@ -28,6 +28,13 @@ unix:OBJECTS_DIR = objects unix:RCC_DIR = objects mac:LIBS += -framework IOKit -framework CoreFoundation +unix { + CONFIG += link_pkgconfig + packagesExist(libudev) { + DEFINES += HAVE_UDEV + PKGCONFIG += libudev + } +} UI_DIR = tmp diff --git a/gui/serial_unix.cc b/gui/serial_unix.cc index 6c65bd0e0..f2995be46 100644 --- a/gui/serial_unix.cc +++ b/gui/serial_unix.cc @@ -21,6 +21,68 @@ #include "mainwindow.h" #if !defined (Q_OS_MAC) // FIXME: find a better way to hide this on Mac. +#ifdef HAVE_UDEV +#include +#include + +static QStringList dynamicDevices() +{ + struct udev *udev = udev_new(); + if(!udev) { + qDebug() << "Can't create udev"; + return QStringList(); + } + + QSet devices; + + struct udev_enumerate *enumerate = udev_enumerate_new(udev); + udev_enumerate_add_match_subsystem(enumerate, "tty"); + udev_enumerate_scan_devices(enumerate); + + struct udev_list_entry *device; + udev_list_entry_foreach(device, udev_enumerate_get_list_entry(enumerate)) { + const char *path = udev_list_entry_get_name(device); + struct udev_device *dev = udev_device_new_from_syspath(udev, path); + + bool okMaj, okMin; + int major = QString(udev_device_get_property_value(dev, "MAJOR")).toInt(&okMaj); + int minor = QString(udev_device_get_property_value(dev, "MINOR")).toInt(&okMin); + if(!okMaj || !okMin) { + major = -1; + minor = -1; + } + + // see Documentation/devices.txt in the linux tree + if( !( (major == 4 || major == 5) && 0 <= minor && minor <= 63 ) ) { + devices << QString::fromUtf8(udev_device_get_devnode(dev)); + /* + udev_device_get_sysattr_list_entry(dev); + udev_device_get_tags_list_entry(dev); + struct udev_list_entry *prop; + qDebug() << "Device Node Path:" << udev_device_get_devnode(dev) << path; + udev_list_entry_foreach(prop, udev_device_get_properties_list_entry(dev)) { + qDebug() << " " << udev_list_entry_get_name(prop) + << "=>" << udev_list_entry_get_value(prop); + } + */ + } + udev_device_unref(dev); + } + udev_enumerate_unref(enumerate); + udev_unref(udev); + + QStringList list = devices.toList(); + qSort(list); + return list; +} +#else +static QStringList dynamicDevices() +{ + return QStringList(); +} +#endif + + static const char *deviceNames[] = { "/dev/ttyS0", "/dev/ttyS1", @@ -33,8 +95,14 @@ static const char *deviceNames[] = { void MainWindow::osLoadDeviceNameCombos(QComboBox *box) { + const QStringList devices = dynamicDevices(); + box->addItems(devices); + for (int i=0; deviceNames[i]; i++) { - box->addItem(deviceNames[i]); + if(!devices.contains(deviceNames[i])) { + box->addItem(deviceNames[i]); + } } } + #endif